package challengeGUI;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.util.Random;

import javax.swing.Timer;

import control.SimpleTimer;

import scaler.Scaler;
import animation.Animator;
import challengesManager.ChallengeManager;
import elements.GameCharacter;
import elements.GameElement;
import elements.GameElementFactory;
import elements.GameElementFactory.Element;

public class ElementCountGUI extends ChallengeGUI {
	private Timer timer;

	private final int minEle = 5;
	private int elements, active = 0, maxUpdates, elementSpeed = 3;
	private Random random;
	private Animator ani[] = new Animator[2];

	public ElementCountGUI(ChallengeManager manager) {
		super(manager);

		random = new Random(System.currentTimeMillis());
		timer = new Timer(DEFAULT_UPDATE, new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				ElementCountGUI.this.update();
			}
		});
		timer.setDelay(DEFAULT_UPDATE);

		for(int i = 0; i<ani.length; i++) {
			ani[i] = new Animator(this);
			ani[i].setBouncing(true);
			ani[i].setForegroundPainting(true);
		}
	}

	@Override
	public void newRound() {
		timer.restart();

		ani[active].stop();
		ani[active].clear();

		elements = minEle + random.nextInt(4);
		maxUpdates = 3 + random.nextInt(5);
		active = 0;

		initAnimator(ani[0]);

		ani[active].start();

		checkNumber();
	}

	@Override
	public void freeze() {
		ani[active].stop();
	}

	@Override
	public void unfreeze() {
		ani[active].start();
	}

	@Override
	public void reveal(final int info) {
//		ani[active].stop();
		ani[active].start();
		timer.stop();

		final GameElement ele[] = ani[active].getElements();

		for(GameElement e : ele) {
			e.fadeOut(true);
		}
		
		SimpleTimer.pause(1000, new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent ev) {
				if(ele.length == elements) {
					for(GameElement e : ele) {
						e.fadeOut(false);
						e.setTransparency(1.0f);
					}
				}
			}
		});
		
//		SimpleTimer.pause(ani[active], 1000);
//		if(ele.length == elements) {
//			for(GameElement e : ele) {
//				e.fadeOut(false);
//				e.setTransparency(1.0f);
//			}
//		}
		
		SimpleTimer.pause(2000, new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				// Right or wrong?
				ani[active].setRightOrWrong(((info==-1)?wrong:right), ElementCountGUI.this.getWidth()/2, ElementCountGUI.this.getHeight()/2);
			}
		});
//		SimpleTimer.pause(ani[active], 1000);
//
//		// Right or wrong?
//		ani[active].setRightOrWrong(((info==-1)?wrong:right), this.getWidth()/2, this.getHeight()/2);

//		SimpleTimer.pause(ani[active], 1500);
		SimpleTimer.pause(3500, new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				manager.animationOver();
			}
		});
	}

	@Override
	public void paint(Graphics g) {
		GameCharacter ch = new GameCharacter(GameElement.NO_MOVEMENT,scaler, "" + elements);
		ch.setColor(Color.DARK_GRAY);
		ch.setFontSize(50);
		ch.setXY(10, 10);
		ch.paint(g);
	}

	/**
	 * Will update the GUI so a new amount of elements is visible
	 * The method will freeze the running Animator and start/unfreeze the new one
	 * 
	 */
	public void update() {
		int old = active;
		// Increase the active counter so the next Animator will be choosen
		active = (active+1) % ani.length;

		initAnimator(ani[active]);
		maxUpdates--;

		ani[old].stop();
		ani[old].clear();

		checkNumber();
		ani[active].start();

		//		// Gives the manager a signal that a update was done
		if(maxUpdates < -1) {
			manager.animationOver();
		}
	}

	@Override
	public void end() {
		for(Animator a : ani) {
			a.stop();
		}
	}

	public int getElementcount() {
		return elements;
	}

	private void initAnimator(Animator a) {
		int eleNumber = elements;
		if(maxUpdates >= 0) {
			eleNumber += random.nextInt(3) - 1;
		}

		// Adds random elements
		GameElement ele;
		for(int i = 0; i<eleNumber; i++) {
			Animator.factory.setRandomSpeed(elementSpeed);
			ele = Animator.factory.newRandomElement(
					GameElementFactory.withoutChar, scaler);
			ele.setRandomPosition(myDim.width, myDim.height);
			ele.setRandomColor();
			a.add(ele);
		}
	}

	private void checkNumber() {
		// Gives the manager a signal if the right number of elements are shown
		if(ani[active].size() == elements) {
			manager.perfectBuzzMoment(true);
		} else {
			manager.perfectBuzzMoment(false);
		}
	}
}
